#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <linux/stddef.h>
#include <RgaUtils.h>
#include <im2d.hpp>
#include "dma_alloc.h"

#include "mpp/rk_struct.h"
#include "base_puller.h"

namespace stream {

#define SET_BYTE(_p, _b) \
    *_p++ = (unsigned char)_b;

#define SET_BUFFER(_p, _buf, _len) \
    memcpy(_p, _buf, _len); \
    (_p) += (_len);

#define CLEAR(x) memset(&(x), 0, sizeof(x))

struct cam_buffer
{
  void* start;
  unsigned int length;
};

class RKStreamPullerUSB:public BasePuller
{
public:
  RKStreamPullerUSB(StreamPullerInfo* spinfo, LogInfo* log_info);
  ~RKStreamPullerUSB();

public:
  int init_params();
  int start_pull();
  int stop_pull();
  int get_frame(stream::ImageBlob& buffer);

private:
  int init_device();
  int init_rockchip();
  int init_mpp();
  int init_rga();
  int start_pull_imp();
  int release_mpp(int ret);
  int release_rga(int ret);
  int copy_buffer(MppFrame &frame,cv::Mat& rgbImg,std::vector<char>& out_buf);

  int openDevice();
  int closeDevice();
  int initDevice();
  int startCapture();
  int stopCapture();
  int freeBuffers();
  int getFrame(void **,size_t *);
  int backFrame();
  int initBuffers();

public:


private:

  std::mutex queue_lock;
  std::queue<stream::ImageBlob> queue_data;

  //rk
  MppCtx ctx;
	MppApi* mpi;
	MppBufferGroup frm_grp;
	MppBufferGroup pkt_grp;
	MppParam param;
	// RK_U32 need_split;
	MpiCmd mpi_cmd;
	size_t max_usage;

  // rga
  int src_format;
  int dst_format;
  int src_buf_size;
  int dst_buf_size;
  int src_dma_fd, dst_dma_fd;
  char* src_buf;
  char* dst_buf;
  rga_buffer_t src_img, dst_img;
  rga_buffer_handle_t src_handle, dst_handle;

  // init module
  // void *display = nullptr;
  // void *vps = nullptr;
  int tmp_cnt;
  int total_yuv2rgb_time = 0;
  int total_yuv2rgb_cnt = 0;


  std::string devName;
  int fd_cam;
  cam_buffer *buffers;
  unsigned int n_buffers;
  int frameIndex;
  

};


}   // namespace camera
